package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.OrderService;
import com.itheima.service.ReportService;
import com.itheima.service.SetMealService;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 吴
 * @version V1.0
 * @Description
 * @Package com.itheima.controller
 * @date 2021/11/30 14:49
 */
@RestController
@RequestMapping("/report")
public class ReportController {

    @Reference
    private MemberService memberService;

    @Reference
    private SetMealService setMealService;

    @Reference
    private ReportService reportService;

    @Reference
    private OrderService orderService;
    /**
     * 前12个月会员统计
     * @return
     */
    @GetMapping("/findMonthMember")
    public Result findMonthMember(){

        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            String[] beforeDates = new String[12];

            for (int i = beforeDates.length - 1; i >= 0; i--) {
                String currentDate = dateFormat.format(calendar.getTime());
                beforeDates[i] = currentDate;
                // 减去一个月
                calendar.add(Calendar.MONTH,-1);
            }
            List<Integer> counts = memberService.findMemberCountByBeforeDate(beforeDates);

            Map<String,Object> map = new HashMap<>();
            // 日期
            map.put("months",beforeDates);
            // 人数
            map.put("memberCount",counts);

            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    /**
     * 查询套餐的预约人数统计
     * @return
     */
    @GetMapping("getSetmealReport")
    public Result getSetmealReport(){
        try {
            List<Map<String, Object>> setmealOrderCount = setMealService.findSetmealOrderCount();

            // 套餐名
            List<String> setmealNames = new ArrayList<>();
            setmealOrderCount.stream().forEach(setmealName->{
                String name = (String)setmealName.get("name");
                setmealNames.add(name);
            });

            // 套餐名+人数
            List<Map<String, Object>> setmealCount = setmealOrderCount;

            Map<String,Object> map = new HashMap<>();

            map.put("setmealNames",setmealNames);
            map.put("setmealCount",setmealCount);

            return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }

    }

    /**
     * 获取运营统计数据
     * @return
     */
    @GetMapping("/getBusinessReportData")
    public Result getBusinessReportData(){

    /*
        HashMap<String, Object> map = new HashMap<>();
        map.put("todayVisitsNumber",10);
        map.put("reportDate","2019-04-25");
        map.put("todayNewMember",2);
        map.put("thisWeekVisitsNumber",100);
        map.put("thisMonthNewMember",300);
        map.put("thisWeekNewMember",30);
        map.put("totalMember",1000);
        map.put("thisMonthOrderNumber",350);
        map.put("thisMonthVisitsNumber",400);
        map.put("todayOrderNumber",12);
        map.put("thisWeekOrderNumber",120);

        List<Map<String,Object>> hotSetmeal = new ArrayList<>();
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("proportion",0.4545);
        map1.put("name","粉红珍爱(女)升级TM12项筛查体检套餐");
        map1.put("setmeal_count",5);
        HashMap<String, Object> map2 = new HashMap<>();
        map2.put("proportion",0.4545);
        map2.put("name","阳光爸妈升级肿瘤12项筛查体检套餐");
        map2.put("setmeal_count",2);
        hotSetmeal.add(map1);
        hotSetmeal.add(map2);

        map.put("hotSetmeal",hotSetmeal);*/

        try {
            Map<String, Object> map = reportService.findBusinessData();
            return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    /**
     * 导出运营统计表 excel
     * @return
     */
    @GetMapping("/exportBusinessExcelReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response){
        XSSFWorkbook workbook = null;
        ServletOutputStream out = null;
        try {
            // 查询运行数据
            Map<String, Object> map = reportService.findBusinessData();

            // 获取准备好的 excel 表的绝对路径   File.separator：分隔符
            String templateRealPath =  request.getSession().getServletContext().getRealPath("template")+ File.separator+"report_template.xlsx";

            // 读取模板文件创建Excel表格对象
            workbook = new XSSFWorkbook(new FileInputStream(new File(templateRealPath)));
            // 读取第一个工作表
            XSSFSheet sheet = workbook.getSheetAt(0);

            // 将数据一一输入对应表格
            // 日期
            XSSFRow row = sheet.getRow(2);
            XSSFCell cell = row.getCell(5);
            cell.setCellValue((String) map.get("reportDate"));
            // 今日新增会员数 todayNewMember
            row = sheet.getRow(4);
            cell = row.getCell(5);
            cell.setCellValue((Integer) map.get("todayNewMember"));
            // 总会员数 totalMember
            row = sheet.getRow(4);
            cell = row.getCell(7);
            cell.setCellValue((Integer) map.get("totalMember"));
            // 本周新增会员数 thisWeekNewMember
            row = sheet.getRow(5);
            cell = row.getCell(5);
            cell.setCellValue((Integer) map.get("thisWeekNewMember"));
            // 本月新增会员数 thisMonthNewMember
            row = sheet.getRow(5);
            cell = row.getCell(7);
            cell.setCellValue((Integer) map.get("thisMonthNewMember"));
            // 今日预约数  todayOrderNumber
            row = sheet.getRow(7);
            cell = row.getCell(5);
            cell.setCellValue((Integer) map.get("todayOrderNumber"));
            // 今日到诊数 todayVisitsNumber
            row = sheet.getRow(7);
            cell = row.getCell(7);
            cell.setCellValue((Integer) map.get("todayVisitsNumber"));
            //  本周预约数 thisWeekOrderNumber
            row = sheet.getRow(8);
            cell = row.getCell(5);
            cell.setCellValue((Integer) map.get("thisWeekOrderNumber"));
            //  本周到诊数 thisWeekVisitsNumber
            row = sheet.getRow(8);
            cell = row.getCell(7);
            cell.setCellValue((Integer) map.get("thisWeekVisitsNumber"));
            // 本月预约数 thisMonthOrderNumber
            row = sheet.getRow(9);
            cell = row.getCell(5);
            cell.setCellValue((Integer) map.get("thisMonthOrderNumber"));
            // 本月到诊数 thisMonthVisitsNumber
            row = sheet.getRow(9);
            cell = row.getCell(7);
            cell.setCellValue((Integer) map.get("thisMonthVisitsNumber"));
            //  热门套餐 hotSetmeal
            AtomicInteger rowNum = new AtomicInteger(12);
            List<Map<String,Object>> hotSetmeals =(List<Map<String,Object>>)map.get("hotSetmeal");
            hotSetmeals.stream().forEach(hotSetmeal->{
                XSSFRow sheetRow = sheet.getRow(rowNum.get());
                sheetRow.getCell(4).setCellValue((String) hotSetmeal.get("name"));
                sheetRow.getCell(5).setCellValue((Long) hotSetmeal.get("setmeal_count"));
                BigDecimal proportion = (BigDecimal) hotSetmeal.get("proportion");
                sheetRow.getCell(6).setCellValue(proportion.doubleValue());
                sheetRow.getCell(7).setCellValue((String) hotSetmeal.get("remark"));
                rowNum.getAndIncrement();
            });

            // 使用输出流输出
            out = response.getOutputStream();
            // 输出格式
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
            workbook.write(out);
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL, null);
        }finally {
            if(out != null){
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(workbook != null){
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 导出运营统计表 pdf
     * @return
     */
    @GetMapping("/exportBusinessPdfReport")
    public Result exportBusinessPdfReport(HttpServletRequest request, HttpServletResponse response){
        try {
            // 查询运行数据
            Map<String, Object> map = reportService.findBusinessData();
            // 热门套餐
            List<Map<String,Object>> hotSetmeals =(List<Map<String,Object>>)map.get("hotSetmeal");

            // pdf模板
            String jrxmlPath =  request.getSession().getServletContext().getRealPath("template")+ File.separator+"health_business3.jrxml";
            // 编译文件保存位置
            String jasperPath = request.getSession().getServletContext().getRealPath("template")+ File.separator+"health_business3.jasper";

            // 编译模板
            JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);

            // 填充数据 编译文件位置，单个参数的集合，循坏的集合
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath,  map,  new JRBeanCollectionDataSource(hotSetmeals));

            // 使用输出流输出
            OutputStream out = response.getOutputStream();
            // 输出格式
            response.setContentType("application/pdf");
            response.setHeader("content-Disposition", "attachment;filename=report.pdf");

            // 输出文件
            JasperExportManager.exportReportToPdfStream(jasperPrint,out);

            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL, null);
        }finally {

        }
    }

    /**
     * 获取每月收入统计
     * 根据id查询已到诊人数和体检套餐名
     * @return
     */
    @GetMapping("/findMonthIncome")
    public Result findMonthIncome(){

        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            String[] beforeDates = new String[12];

            for (int i = beforeDates.length - 1; i >= 0; i--) {
                String currentDate = dateFormat.format(calendar.getTime());
                beforeDates[i] = currentDate;
                // 减去一个月
                calendar.add(Calendar.MONTH,-1);
            }
            List<Integer> income = orderService.findOrderCountAndSetmealNameByBeforeDate(beforeDates);

            Map<String,Object> map = new HashMap<>();
            // 日期
            map.put("months",beforeDates);
            // 人数
            map.put("income",income);

            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    /**
     * 前12个月预约统计和支付统计
     * @return
     */
    @GetMapping("/findMonthOrder")
    public Result findMonthOrder(){

        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            String[] beforeDates = new String[12];

            for (int i = beforeDates.length - 1; i >= 0; i--) {
                String currentDate = dateFormat.format(calendar.getTime());
                beforeDates[i] = currentDate;
                // 减去一个月
                calendar.add(Calendar.MONTH,-1);
            }
            List<Map> map = orderService.findCountAndPay(beforeDates);

            Map<String,Object> map1 = new HashMap<>();
            // 日期
            map1.put("months",beforeDates);
            // 预约人数
            map1.put("map",map);

            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map1);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }
}
